<!--
 * @Author: syl
 * @Date: 2023-09-20 13:46:27
 * @LastEditors: syl
 * @LastEditTime: 2023-09-27 14:53:17
 * @FilePath: \G6Doemo\g6\src\components\HelloWorld.vue
 * @Description: 
 * 
 * Copyright (c) 2023 by junlin, All Rights Reserved. 
-->
<!--
 * @Author: syl
 * @Date: 2023-09-20 13:46:27
 * @LastEditors: syl
 * @LastEditTime: 2023-09-21 10:46:13
 * @FilePath: \G6Doemo\g6\src\components\HelloWorld.vue
 * @Description: 
 * 
 * Copyright (c) 2023 by junlin, All Rights Reserved. 
-->
<template>
  <div class="hello" style="position: relative">
    <div class="control" style="">
      <div style="margin-bottom: 20px">
        <p style="color: #fff;">筛选：</p>
        <div>
          <span @click="lookDetail">详细线索</span><span style="margin-left: 20px" @click="lookKey">关键线索</span>
        </div>
      </div>
      <div id="miniContainer">
      </div>
    </div>
    <div id="mountNode" style="background-color: #000000d9;height: calc(100vh - 110px);"></div>
  </div>
</template>

<script>
import G6 from "@antv/g6";
import remoteData from "./testData.json";
import findAssociatedNodes from './findCurrentNodeRelationNodes'
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  data() {
    return {
      graph: null,
      data: null,
      keyData: {
        nodes: [],
        edges: [],
      },
      sourceNodesId: [],
      targetNodesId: [],
      keyNodeIds: [],
      allNodeId: [],
      allKeyNodes: [],
      allKeyEdges: [],
    };
  },
  mounted() {
    this.data = remoteData
    this.initG6(this.data);
  },
  methods: {
    // 查找初hot==2和人员节点的关键线索
    findKeyClue({ keyNodeIds = [], nodes, edges, isIncludeSelf = false, dataType = 'g6Data' }) {
      console.log(1233);
      let sourceNodeIds = []
      let targetNodeIds = []
      let allNodeIds = []
      let allKeyNodes = [] //不包含本身
      let allKeyEdges = [] //不包含本身
      console.log('关键节点', keyNodeIds);
      keyNodeIds.forEach(nodeId => {
        let sourceNodesId = new findAssociatedNodes().findSourceNodes(nodeId, edges)
        let targetNodesId = new findAssociatedNodes().findTargetNodes(nodeId, edges)
        if (sourceNodesId.length != 0) {
          sourceNodesId.forEach(i => {
            if (!sourceNodeIds.includes(i)) {
              sourceNodeIds.push(i)
            }
          })
          targetNodesId.forEach(i => {
            if (!targetNodeIds.includes(i)) {
              targetNodeIds.push(i)
            }
          })
        }
      })
      if (isIncludeSelf) {
        allNodeIds.push(...sourceNodeIds, ...targetNodeIds, ...keyNodeIds)
      } else {
        allNodeIds.push(...sourceNodeIds, ...targetNodeIds)
      }

      nodes.forEach(item => {
        if (allNodeIds.includes(item.id)) {
          if (!allKeyNodes.includes(item)) {
            allKeyNodes.push(item)
          }
        }
      })
      console.log('关键节点', allNodeIds);
      // console.log('所有的关键节点',this.allKeyNodes,this.allNodeId);
      edges.forEach(edge => {
        if (allNodeIds.includes(edge.target) && allNodeIds.includes(edge.source)) {
          allKeyEdges.push(edge)
        }
      })
      let data = {
        nodes: allKeyNodes,
        edges: allKeyEdges
      }
      if (dataType == 'g6Data') {
        return data
      } else {
        return allNodeIds
      }

    },
    lookDetail() {
      this.graph.read(this.data)
    },
    lookKey() {
      const keyNodeIds = []
      this.data.nodes.forEach(node => {
        if (node.hot > 1 || node.cluster == '6') {
          keyNodeIds.push(node.id)
        }
      })
      this.keyData = this.findKeyClue({
        keyNodeIds,
        nodes: this.data.nodes,
        edges: this.data.edges,
        isIncludeSelf: true,
        dataType: 'g6Data'
      }
      )
      this.graph.read(this.keyData)
    },
    initG6(testData = null) {
      let vm = this;
      // data.edges.forEach((item, index) => {
      //   item.id = `edge-${index}`;
      // });
      // const colors = [
      //   "rgba(64, 158, 255, 0.15)",//案件开始节点
      //   "rgba(51, 34, 249, 0.10)",//wifimac
      //   "rgba(71, 178, 18, 0.10)",//机身信息
      //   "rgba(249, 34, 249, 0.10)",//ip
      //   "rgba(245, 108, 108, 0.15)",//人员
      //   "rgba(206, 209, 24, 0.10)",//社交账号
      //   "rgba(26, 168, 192, 0.10)",//通讯号码
      //   "rgba(229, 137, 46, 0.10)",//资金账户
      //   "#AAD8D8",
      //   "#FFD6E7",
      // ];
      const colors = [
        "rgba(64, 158, 255,0.7)",//案件开始节点
        "rgba(51, 34, 249,0.7)",//wifimac
        "rgba(71, 178, 18,0.7)",//机身信息
        "rgba(249, 34, 249,0.7)",//ip
        "rgba(245, 108, 108,0.7)",//人员
        "rgba(206, 209, 24,0.7)",//社交账号
        "rgba(26, 168, 192,0.7)",//通讯号码
        "rgba(229, 137, 46,0.7)",//资金账户
        "#AAD8D8",
        "#FFD6E7",
      ];
      const strokes = [
        "rgba(64, 158, 255)",//案件开始节点
        "rgba(51, 34, 249)",//wifimac
        "rgba(71, 178, 18)",//机身信息
        "rgba(249, 34, 249)",//ip
        "rgba(245, 108, 108)",//人员
        "rgba(206, 209, 24)",//社交账号
        "rgba(26, 168, 192)",//通讯号码
        "rgba(229, 137, 46)",//资金账户
        "#269A99",
        "#FF99C3",
      ];
      const textColors = [
        "rgba(64, 158, 255)",//案件开始节点
        "rgba(51, 34, 249)",//wifimac
        "rgba(71, 178, 18)",//机身信息
        "rgba(249, 34, 249)",//ip
        "rgba(245, 108, 108)",//人员
        "rgba(206, 209, 24)",//社交账号
        "rgba(26, 168, 192)",//通讯号码
        "rgba(229, 137, 46)",//资金账户
        "#269A99",
        "#FF99C3",
      ]      // const timeBarData = [
      //   {
      //     date: `20200622`,
      //     value: Math.round(Math.random() * 300),
      //   },
      //   {
      //     date: `20210622`,
      //     value: Math.round(Math.random() * 300),
      //   },
      //   {
      //     date: `2022`,
      //     value: Math.round(Math.random() * 300),
      //   },
      //   {
      //     date: `2023`,
      //     value: Math.round(Math.random() * 300),
      //   },
      //   {
      //     date: `2024`,
      //     value: Math.round(Math.random() * 300),
      //   },
      // ];
      // const timebar = new G6.TimeBar({
      //   x: 0,
      //   y: 0,
      //   width: 500,
      //   height: 150,
      //   padding: 10,
      //   type: "trend",
      //   trend: {
      //     data: timeBarData,
      //   },
      // });
      G6.registerNode(
        "rect-xml",
        {
          draw(cfg, group) {
            // 如果 cfg 中定义了 style 需要同这里的属性进行融合
            const keyShape = group.addShape("circle", {
              attrs: {
                x: 0,
                y: 0,
                r: 60,
                fill: cfg.style.fill,
                stroke: cfg.style.stroke,
                lineWidth: 2
              },
              // 在 G6 3.3 及之后的版本中，必须指定 name，可以是任意字符串，但需要在同一个自定义元素类型中保持唯一性
              name: "circle-shape",
              // 设置 draggable 以允许响应鼠标的图拽事件
              draggable: true,
            });
            if (cfg.label) {
              let arr = cfg.nodeAttribute.name
              let arrCopy = arr
              let value
              let content = ''
              if (arr && cfg.nodeAttribute.name.search(',') != -1) {
                value = arrCopy.split(',')[1]
                content = value.replace(/(.{10})/g, "$1\n");
              }
              console.log(arrCopy);
              group.addShape("text", {
                // attrs: style
                attrs: {
                  x: 0, // 居中
                  y: -20,
                  textAlign: "center",
                  textBaseline: "middle",
                  text: content,
                  // fill: cfg.labelCfg.style.fill,
                  fill: '#fff',
                  fontSize: 16,
                  fontWeight: 500,
                },
                // 在 G6 3.3 及之后的版本中，必须指定 name，可以是任意字符串，但需要在同一个自定义元素类型中保持唯一性
                name: "text-shape1",
                // 设置 draggable 以允许响应鼠标的图拽事件
                draggable: true,
              });
              group.addShape("text", {
                // attrs: style
                attrs: {
                  x: 0, // 居中
                  y: content?30:0,
                  textAlign: "center",
                  textBaseline: "middle",
                  text: cfg.label,
                  // fill: cfg.labelCfg.style.fill,
                  fill: '#fff',
                  fontSize: 16,
                  fontWeight: 500,

                },
                // 在 G6 3.3 及之后的版本中，必须指定 name，可以是任意字符串，但需要在同一个自定义元素类型中保持唯一性
                name: "text-shape4",
                // 设置 draggable 以允许响应鼠标的图拽事件
                draggable: true,
              });
            }
            return keyShape;
          },
          /**
           * 绘制后的附加操作，默认没有任何操作
           * @param  {Object} cfg 节点的配置项
           * @param  {G.Group} group 图形分组，节点中的图形对象的容器
           */
          // afterDraw(cfg, group) {},
          /**
           * 更新节点，包含文本
           * @override
           * @param  {Object} cfg 节点的配置项
           * @param  {Node} node 节点
           */
          // update(cfg, node) {},
          /**
           * 更新节点后的操作，一般同 afterDraw 配合使用
           * @override
           * @param  {Object} cfg 节点的配置项
           * @param  {Node} node 节点
           */
          // afterUpdate(cfg, node) {},
          /**
           * 设置节点的状态，主要是交互状态，业务状态请在 draw 方法中实现
           * 单图形的节点仅考虑 selected、active 状态，有其他状态需求的用户自己复写这个方法
           * @param  {String} name 状态名称
           * @param  {Object} value 状态值
           * @param  {Node} node 节点
           */
          // setState(name, value, node) {},
          /**
           * 获取锚点（相关边的连入点）
           * @param  {Object} cfg 节点的配置项
           * @return {Array|null} 锚点（相关边的连入点）的数组,如果为 null，则没有锚点
           */
          // getAnchorPoints(cfg) {},
        },
        "circle"
      );
      const lineDash = [4, 2, 1, 2];
      G6.registerEdge(
        "can-running",
        {
          setState(name, value, item) {
            const shape = item.get("keyShape");
            if (name === "running") {
              if (value) {
                let index = 0;
                shape.animate(
                  () => {
                    index++;
                    if (index > 9) {
                      index = 0;
                    }
                    const res = {
                      lineDash,
                      lineDashOffset: -index,
                    };
                    // return the params for this frame
                    return res;
                  },
                  {
                    repeat: true,
                    duration: 3000,
                  }
                );
              } else {
                shape.stopAnimate();
                shape.attr("lineDash", null);
              }
            }
          },
        },
        "cubic-horizontal"
      );
      const minimap = new G6.Minimap({
        container: "miniContainer",

        size: [150, 150],
        className: "minimap",
        type: "keyShape",
        hideEdge: true,
      });
      const menu = new G6.Menu({
        offsetX: 6,
        offsetY: 10,
        itemTypes: ["node"],
        className: "menu-content",
        trigger: "contextmenu",

        getContent(e) {
          console.log(e);
          const contextmenu = document.createElement("div");
          contextmenu.innerHTML = `
          <div 
          style="
          width: 100px;
          height: 98px;
          background: #FFFFFF;
          border-radius: 4px 4px 4px 4px;
          opacity: 1;
          border: 1px solid #E4E7ED;
          box-shadow: 1px 1px 0px 2px #E4E7ED;
          display: flex;
          justify-content: flex-start;
          flex-direction: column;
          "
          >
            <div style="padding:5px;magin-bottom:5px;cursor: pointer;color:#409EFF">
              <span>详情</span>
            </div>
            <div style="padding:5px;magin-bottom:5px;cursor: pointer;color:#409EFF">
             <span>查询</span>
            </div>
            <div style="padding:5px;cursor: pointer;color:#409EFF">
              <span>判定</span>
            </div>
            </div>
          `;
          return contextmenu;
        },
        handleMenuClick(target, item) {
          console.log(33333, target, item);
        },
        shouldBegin(e) {
          console.log(e, "是否出现menu");
          return true;
        },
      });
      const tooltip = new G6.Tooltip({
        offsetX: 10,
        offsetY: 10,
        // v4.2.1 起支持配置 trigger，click 代表点击后出现 tooltip。默认为 mouseenter
        trigger: "hover",
        // container:'tooltip',
        // className:'tooltip-class',
        itemTypes: ["node", "edge"],
        fixToNode: [0.5, 0.5],
        // 自定义 tooltip 内容
        shouldBegin(e) {
          //是否允许出现
          console.log(e);
          return false;
        },
        getContent: (e) => {
          const outDiv = document.createElement("div");
          outDiv.style.width = "fit-content";
          //outDiv.style.padding = '0px 0px 20px 0px';
          outDiv.innerHTML = `
      <h4>Custom Content</h4>
      <ul>
        <li>Type: ${e.item.getType()}</li>
      </ul>
      <ul>
        <li>Label: ${e.item.getModel().label || e.item.getModel().id}</li>
      </ul>`;
          return outDiv;
        },
      });
      const nodes = testData.nodes;
      const edges = testData.edges;
      const clusterMap = new Map();
      let clusterId = 0;
      edges.forEach((edge, index) => {
        edge.id = String(edge.id) + index;
      });
      console.log(edges, 2389778578785);
      nodes.forEach(function (node) {
        node.id = String(node.id);
        // cluster
        if (node.cluster && clusterMap.get(node.cluster) === undefined) {
          clusterMap.set(node.cluster, clusterId);
          clusterId++;
        }
        const cid = clusterMap.get(node.cluster);
        if (!node.style) {
          node.style = {};
        }
        node.style.fill = colors[cid % colors.length];
        node.style.stroke = strokes[cid % strokes.length];
        node.labelCfg['style'].fill = textColors[cid % colors.length];
      });
      G6.Util.processParallelEdges(testData.edges);
      const container = document.getElementById("mountNode");
      const width = container.scrollWidth;
      const height = container.scrollHeight || 500;
      // const width = 800;
      // const height = 800;
      vm.graph = new G6.Graph({
        container: "mountNode",
        width,
        height,
        animate: true, // Boolean，可选，全局变化时否使用动画过渡
        renderer: "canvas",
        fitView: true, //自适应画布
        // fitViewPadding: "", //画布留白
        fitCenter: true,
        endArrow: {
          path: G6.Arrow.triangle(),
        },
        layout: {
          type: "force2",
          animate: true, // 设置为 false 可关闭布局动画
          maxSpeed: 1000,
          linkDistance: 350,
          nodeSize: 60,
          clustering: true,
          nodeClusterBy: "cluster",
          clusterNodeStrength: 600,
          leafCluster: true,
          preventOverlap: true,
          factor: 20,
          damping: 0.1,
          edgeStrength: 400,
          // preset:{
          //   type: 'grid', // 布局名称，可以是 random、concentric、grid、circular、radial、dagre 等静态布局
          //   // [key: string]: unkown; // 对应布局的配置项
          // }
        },
        modes: {
          default: [
            "click-select",
            "drag-node",
            {
              type: "drag-canvas",
              enableOptimize: true, // enable the optimize to hide the shapes beside nodes' keyShape
            },
            {
              type: "zoom-canvas",
              enableOptimize: true, // enable the optimize to hide the shapes beside nodes' keyShape
            },
          ], // 允许拖拽画布、放缩画布、拖拽节点
        },
        groupByTypes: false,
        defaultCombo: {
          // ... 其他属性
          style: {
            fill: "#fff",
            stroke: "pink",
            lineWidth: 2,
            opacity: 0.3,
            fillOpacity: 0.2,
            // ... 其他属性
          },
        },
        defaultNode: {
          type: "rect-xml",
          size: 60,
          style: {
            fill: "#fff",
            // stroke: "#5B8FF9",
          },
          labelCfg: {
            style: {
              fill: "#000",
              fontSize: 18
            },
          },
        },
        defaultEdge: {
          style: {
            fill: "#44494c",
            stroke: "#44494c",
            endArrow: true,
            lineWidth: 3,
            // lineWidth:4
            lineAppendWidth: 5
          },
          labelCfg: {
            autoRotate: true,
            style: {
              fill: "#1890ff",
              fontSize: 6,
              background: {
                // fill: "#ffffff",
                // stroke: "#9EC9FF",
                padding: [2, 2, 2, 2],
                radius: 5,
              },
            },
          },
        },
        nodeStateStyles: {
          // 鼠标 hover 上节点，即 hover 状态为 true 时的样式
          hover: {
            // fill: "red",
            // stroke: "#fff",
            labelCfg: {
              style: {
                fill: "#fff",
              },
            },
          },
          highlight: {
            opacity: 1,
            fill: "#f40",
            labelCfg: {
              style: {
                fill: "red",
              },
            },
          },
          inactive: {
            opacity: 0.1,
            fontSize: 40,
            labelCfg: {
              style: {
                fill: "red",
                opacity: 0.1,
                fontStyle: 'red'
              },
            },
          },
          // 鼠标点击节点，即 click 状态为 true 时的样式
          click: {
            stroke: "red",
            lineWidth: 3,
          },
          active: {
            stroke: "red",
            lineWidth: 3,
          }
        },
        // 边不同状态下的样式集合
        edgeStateStyles: {
          // 鼠标点击边，即 click 状态为 true 时的样式
          click: {
            stroke: "red",
          },
          highlight: {
            stroke: "#f40",
            lineWidth: 4
          },
          inactive: {
            opacity: 0.1,
          },
          active: {
            stroke: "red",
          },
        },
        plugins: [minimap, tooltip, menu], // 将 minimap 实例配置到图上
      });

      vm.graph.data(testData);
      vm.graph.render();
      // 清除所有状态
      function clearAllStats() {
        vm.graph.setAutoPaint(false);
        vm.graph.getNodes().forEach(function (node) {
          vm.graph.clearItemStates(node, ["inactive", "highlight"]);
        });
        vm.graph.getEdges().forEach(function (edge) {
          vm.graph.clearItemStates(edge);
        });
        vm.graph.paint();
        vm.graph.setAutoPaint(true);
      }
      /******** 拖拽固定节点的逻辑 *********/
      vm.graph.on("node:dragstart", function () {
        const forceLayout = vm.graph.get("layoutController").layoutMethods[0];
        forceLayout.stop();
      });
      vm.graph.on("node:drag", function (e) {
        refreshDragedNodePosition(e);
        vm.graph.layout();
        if (vm.graph.getHulls() && vm.graph.getHulls()["leafNodeHull"]) {
          const neighbors = vm.graph.getHulls()["leafNodeHull"].members;
          vm.graph.removeHulls(); //移除所有得包裹
          const hull = vm.graph.createHull({
            //包裹元素
            id: "leafNodeHull",
            members: neighbors,
            padding: 10,
            style: {
              fill: "lightgreen",
              stroke: "green",
              opacity: 0.2,
            },
          });
          hull.updateData(hull.members);
        }
      });
      // 鼠标进入节点
      vm.graph.on("node:mouseenter", (e) => {
        const item = e.item; // 获取鼠标进入的节点元素对象
        vm.graph.setItemState(item, "hover", true); // 设置当前节点的 hover 状态为 true
      });
      // vm.graph.on("node:mouseleave", clearAllStats);
      vm.graph.on("canvas:click", () => {
        clearAllStats();
        // vm.graph.removeHulls(); //移除所有得包裹
        vm.graph.layout();
        // vm.graph.changeData(data);
        const nodes = vm.graph.getNodes();
        nodes.forEach((node) => {
          node.toFront();
        });

      });
      // 鼠标离开节点
      vm.graph.on("node:mouseleave", (e) => {
        const nodeItem = e.item; // 获取鼠标离开的节点元素对象
        vm.graph.setItemState(nodeItem, "hover", false); // 设置当前节点的 hover 状态为 false
      });
      // 点击节点
      vm.graph.on("node:click", (e) => {
        // 先将所有当前是 click 状态的节点置为非 click 状态
        const clickNodes = vm.graph.findAllByState("node", "click");
        clickNodes.forEach((cn) => {
          vm.graph.setItemState(cn, "click", false);
        });
        const item = e.item; // 获取被点击的节点元素对象
        vm.graph.setItemState(item, "click", true); // 设置当前节点的 click 状态为 true
        // // 遍历节点实例，将所有节点z-index提高。
        const nodes = vm.graph.getNodes();
        nodes.forEach((node) => {
          node.toFront();
        });
        vm.graph.focusItem(item); //聚焦点击节点到画布中心
        // vm.graph.removeHulls();
        const neighbors = item.getNeighbors(); //获取相邻节点
        const edges = item.getEdges(); //获取节点关联得边;
        neighbors.push(item);
        // const hull = vm.graph.createHull({
        //   id: "leafNodeHull",
        //   members: neighbors,
        //   padding: 10,
        //   style: {
        //     fill: "lightgreen",
        //     stroke: "green",
        //     opacity: 0.2,
        //   },
        // });
        // hull.updateData(hull.members);
        vm.graph.setItemState(item, "active", true); // 设置当前节点的 click 状态为 true
        // vm.graph.priorityState(item, "active");
        vm.graph.setAutoPaint(false);
        vm.graph.getNodes().forEach(function (node) {
          vm.graph.clearItemStates(node);
          vm.graph.setItemState(node, "inactive", true);
        });
        vm.graph.setItemState(item, "inactive", false);
        vm.graph.setItemState(item, "highlight", true);
        let id = item.getModel().id
        console.log('当前节点id', id);
        let highlightNodeIds = vm.findKeyClue(
          {
            keyNodeIds: [id],
            nodes: vm.data.nodes,
            edges: vm.data.edges,
            isIncludeSelf: true,
            dataType: 'ids'
          })
        console.log('高亮节点id22222222', highlightNodeIds, vm.graph.getNodes());
        vm.graph.getEdges().forEach(function (edge) {
          if (highlightNodeIds.includes(edge.getSource()._cfg.id) && highlightNodeIds.includes(edge.getTarget()._cfg.id)) {
            vm.graph.setItemState(edge.getTarget(), "inactive", false);
            vm.graph.setItemState(edge.getTarget(), "highlight", true);
            vm.graph.setItemState(edge.getSource(), "highlight", true);
            if (edge.getSource()._cfg.id == '1698834364021866502' && edge.getTarget() != item) {
              vm.graph.setItemState(edge, "highlight", false);
            } else {
              vm.graph.setItemState(edge, "highlight", true);
            }

            edge.toFront();
            const source = edge.getSource();
            // 该边的结束点
            const target = edge.getTarget();
            // 先将边提前，再将端点提前。这样该边两个端点还是在该边上层，较符合常规。
            edge.toFront();
            source.toFront();
            target.toFront();
          } else {
            vm.graph.setItemState(edge, "highlight", false);
          }
        });

        console.log(vm, edges);
        // const dataCopy = { nodes: [], edges: [] };
        // neighbors.forEach((item) => {
        //   data.nodes.filter(ele=>{
        //     if( item._cfg.id==ele.id){
        //       dataCopy.nodes.push(ele);
        //     }
        //   })
        // });
        // console.log(e,vm, "当前点击节点得边");
        // edges.forEach((item) => {
        //   data.edges.filter(ele=>{
        //     if( item._cfg.id==ele.id){
        //       dataCopy.edges.push(ele);
        //     }
        //   })
        // });
        // if(dataCopy.edges.length>0){
        //   vm.graph.changeData(dataCopy);
        // }
        sonNodeSLayout(item);
        vm.graph.paint();
        vm.graph.setAutoPaint(true);
      });
      // vm.graph.read(vm.keyData)
      // 点击边
      vm.graph.on("edge:click", (e) => {
        // 先将所有当前是 click 状态的边置为非 click 状态
        const clickEdges = vm.graph.findAllByState("edge", "click");
        clickEdges.forEach((ce) => {
          vm.graph.setItemState(ce, "click", false);
        });
        const edgeItem = e.item; // 获取被点击的边元素对象
        vm.graph.setItemState(edgeItem, "click", true); // 设置当前边的 click 状态为 true
      });
      // vm.graph.on("nodeselectchange", (e) => {
      //   console.log(e.selectedItems, e.select);
      // });
      // vm.graph.on("tooltipchange", (e) => {
      //   console.log(e, "tootip改变了");
      // });
      function sonNodeSLayout(node) {
        let currentClickNodeId = node.getModel().id;
        // const data = vm.findKeyClue([currentClickNodeId],vm.data.nodes,vm.data.edges,false)
        const data = vm.findKeyClue({
          keyNodeIds: [currentClickNodeId],
          nodes: vm.data.nodes,
          edges: vm.data.edges,
          isIncludeSelf: false,
          dataType: 'g6Data'
        })
        // const newNodes = [];
        // const newEdges = [];
        // let relationNodeId = [];
        // testData.edges.forEach(function (edge) {
        //   if (edge.source == currentClickNodeId) {
        //     newEdges.push(edge);
        //     relationNodeId.push(edge.target);
        //   }
        // });
        // testData.nodes.forEach(function (item) {
        //   if (relationNodeId.includes(item.id)) {
        //     newNodes.push(item);
        //   }
        // });
        // console.log("测试", newNodes);
        // console.log("线", newEdges);

        const subForceLayout = new G6.Layout.circular({
          center: [node.getBBox().centerX, node.getBBox().centerY], // 可选，默认为图的中心
          radius: 300, // 可选
          startRadius: 100, // 可选
          endRadius: 300, // 可选
          clockwise: false, // 可选
          divisions: 5, // 可选
          ordering: "degree", // 可选
          angleRatio: 1, // 可选
          workerEnabled: true,
          // },
        });

        subForceLayout.init(data);
        subForceLayout.execute();
        vm.graph.positionsAnimate();
      }

      function refreshDragedNodePosition(e) {
        const model = e.item.get("model");
        model.fx = e.x;
        model.fy = e.y;
        model.x = e.x;
        model.y = e.y;
      }
      /*********************************/
      // 算法
      if (typeof window !== "undefined")
        window.onresize = () => {
          if (!vm.graph || vm.graph.get("destroyed")) return;
          if (!container || !container.scrollWidth || !container.scrollHeight)
            return;
          vm.graph.changeSize(container.scrollWidth, container.scrollHeight);
        };
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style  scoped>
.control {
  position: fixed;
  top: 100px;
  left: 8px;
  height: calc(100% - 100px);
  background-color: rgba(0, 0, 0, 0.5);
  padding: 10px 10px 0 10px;
  text-align: left;
  display: flex;
  justify-content: space-between;
  flex-direction: column;

}

.control span {
  padding: 5px 10px;
  margin-top: 45px;
  border-radius: 8px;
  cursor: pointer;
  background-color: rgba(101, 170, 177, 0.5);
  color: #ffffff;
}

.g6-tooltip,
.g6-node-tooltip {
  border: 1px solid #262525;
  border-radius: 4px;
  font-size: 12px;
  color: #545454;
  background-color: rgba(255, 255, 255, 0.9);
  padding: 10px 8px;
  box-shadow: rgb(174, 174, 174) 0px 0px 10px;
}

.tooltip-class {
  color: red !important;
  background-color: rgba(0, 0, 0, 0.2) !important;
  border: 1px solid red;
}

/* 右键菜单下拉框得样式 */
.contextmenu {
  width: 170px;
  height: 220px;
  background-color: #b2b1b1;
  transition: all 0.3s;
  color: #fff;
  box-shadow: 2px 2px 1px #b5b4b4;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

h3 {
  margin: 40px 0 0;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>
